<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Tag
 * @subpackage Cloud
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: HtmlTag.php 18951 2009-11-12 16:26:19Z alexander $
 */

/**
 * @see Zend_Tag_Cloud_Decorator_Tag
 */
require_once 'Zend/Tag/Cloud/Decorator/Tag.php';

/**
 * Simple HTML decorator for tags
 *
 * @category  Zend
 * @package   Zend_Tag
 * @uses      Zend_Tag_Cloud_Decorator_Tag
 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag
{
	/**
	 * List of tags which get assigned to the inner element instead of
	 * font-sizes.
	 *
	 * @var array
	 */
	protected $_classList = null;

	/**
	 * Unit for the fontsize
	 *
	 * @var string
	 */
	protected $_fontSizeUnit = 'px';

	/**
	 * Allowed fontsize units
	 *
	 * @var array
	 */
	protected $_alloweFontSizeUnits = array('em', 'ex', 'px', 'in', 'cm', 'mm', 'pt', 'pc', '%');

	/**
	 * List of HTML tags
	 *
	 * @var array
	 */
	protected $_htmlTags = array(
        'li'
        );

        /**
         * Maximum fontsize
         *
         * @var integer
         */
        protected $_maxFontSize = 20;

        /**
         * Minimum fontsize
         *
         * @var integer
         */
        protected $_minFontSize = 10;

        /**
         * Set a list of classes to use instead of fontsizes
         *
         * @param  array $classList
         * @throws Zend_Tag_Cloud_Decorator_Exception When the classlist is empty
         * @throws Zend_Tag_Cloud_Decorator_Exception When the classlist contains an invalid classname
         * @return Zend_Tag_Cloud_Decorator_HtmlTag
         */
        public function setClassList(array $classList = null)
        {
        	if (is_array($classList)) {
        		if (count($classList) === 0) {
        			require_once 'Zend/Tag/Cloud/Decorator/Exception.php';
        			throw new Zend_Tag_Cloud_Decorator_Exception('Classlist is empty');
        		}

        		foreach ($classList as $class) {
        			if (!is_string($class)) {
        				require_once 'Zend/Tag/Cloud/Decorator/Exception.php';
        				throw new Zend_Tag_Cloud_Decorator_Exception('Classlist contains an invalid classname');
        			}
        		}
        	}

        	$this->_classList = $classList;
        	return $this;
        }

        /**
         * Get class list
         *
         * @return array
         */
        public function getClassList()
        {
        	return $this->_classList;
        }

        /**
         * Set the font size unit
         *
         * Possible values are: em, ex, px, in, cm, mm, pt, pc and %
         *
         * @param  string $fontSizeUnit
         * @throws Zend_Tag_Cloud_Decorator_Exception When an invalid fontsize unit is specified
         * @return Zend_Tag_Cloud_Decorator_HtmlTag
         */
        public function setFontSizeUnit($fontSizeUnit)
        {
        	if (!in_array($fontSizeUnit, $this->_alloweFontSizeUnits)) {
        		require_once 'Zend/Tag/Cloud/Decorator/Exception.php';
        		throw new Zend_Tag_Cloud_Decorator_Exception('Invalid fontsize unit specified');
        	}

        	$this->_fontSizeUnit = (string) $fontSizeUnit;
        	$this->setClassList(null);
        	return $this;
        }

        /**
         * Retrieve font size unit
         *
         * @return string
         */
        public function getFontSizeUnit()
        {
        	return $this->_fontSizeUnit;
        }
        /**
         * Set the HTML tags surrounding the <a> element
         *
         * @param  array $htmlTags
         * @return Zend_Tag_Cloud_Decorator_HtmlTag
         */
        public function setHtmlTags(array $htmlTags)
        {
        	$this->_htmlTags = $htmlTags;
        	return $this;
        }

        /**
         * Get HTML tags map
         *
         * @return array
         */
        public function getHtmlTags()
        {
        	return $this->_htmlTags;
        }

        /**
         * Set maximum font size
         *
         * @param  integer $maxFontSize
         * @throws Zend_Tag_Cloud_Decorator_Exception When fontsize is not numeric
         * @return Zend_Tag_Cloud_Decorator_HtmlTag
         */
        public function setMaxFontSize($maxFontSize)
        {
        	if (!is_numeric($maxFontSize)) {
        		require_once 'Zend/Tag/Cloud/Decorator/Exception.php';
        		throw new Zend_Tag_Cloud_Decorator_Exception('Fontsize must be numeric');
        	}

        	$this->_maxFontSize = (int) $maxFontSize;
        	$this->setClassList(null);
        	return $this;
        }

        /**
         * Retrieve maximum font size
         *
         * @return int
         */
        public function getMaxFontSize()
        {
        	return $this->_maxFontSize;
        }

        /**
         * Set minimum font size
         *
         * @param  int $minFontSize
         * @throws Zend_Tag_Cloud_Decorator_Exception When fontsize is not numeric
         * @return Zend_Tag_Cloud_Decorator_HtmlTag
         */
        public function setMinFontSize($minFontSize)
        {
        	if (!is_numeric($minFontSize)) {
        		require_once 'Zend/Tag/Cloud/Decorator/Exception.php';
        		throw new Zend_Tag_Cloud_Decorator_Exception('Fontsize must be numeric');
        	}

        	$this->_minFontSize = (int) $minFontSize;
        	$this->setClassList(null);
        	return $this;
        }

        /**
         * Retrieve minimum font size
         *
         * @return int
         */
        public function getMinFontSize()
        {
        	return $this->_minFontSize;
        }

        /**
         * Defined by Zend_Tag_Cloud_Decorator_Tag
         *
         * @param  Zend_Tag_ItemList $tags
         * @return array
         */
        public function render(Zend_Tag_ItemList $tags)
        {
        	if (null === ($weightValues = $this->getClassList())) {
        		$weightValues = range($this->getMinFontSize(), $this->getMaxFontSize());
        	}

        	$tags->spreadWeightValues($weightValues);

        	$result = array();

        	foreach ($tags as $tag) {
        		if (null === ($classList = $this->getClassList())) {
        			$attribute = sprintf('style="font-size: %d%s;"', $tag->getParam('weightValue'), $this->getFontSizeUnit());
        		} else {
        			$attribute = sprintf('class="%s"', htmlspecialchars($tag->getParam('weightValue')));
        		}

        		$tagHtml = sprintf('<a href="%s" %s>%s</a>', htmlSpecialChars($tag->getParam('url')), $attribute, $tag->getTitle());

        		foreach ($this->getHtmlTags() as $key => $data) {
        			if (is_array($data)) {
        				$htmlTag    = $key;
        				$attributes = '';

        				foreach ($data as $param => $value) {
        					$attributes .= ' ' . $param . '="' . htmlspecialchars($value) . '"';
        				}
        			} else {
        				$htmlTag    = $data;
        				$attributes = '';
        			}

        			$tagHtml = sprintf('<%1$s%3$s>%2$s</%1$s>', $htmlTag, $tagHtml, $attributes);
        		}

        		$result[] = $tagHtml;
        	}

        	return $result;
        }
}
